package com.sunwayhorizo.health.business.patad.encounter;

import java.util.*;
import javax.ejb.*;
import org.jboss.seam.*;
import org.jboss.seam.annotations.*;
import com.sunwayhorizo.health.business.base.*;
import com.sunwayhorizo.health.business.clinic.emr.emrmanager.*;
import com.sunwayhorizo.health.business.dto.*;
import com.sunwayhorizo.health.business.dto.clinic.emr.emrmanager.*;
import com.sunwayhorizo.health.business.dto.patad.encounter.*;
import com.sunwayhorizo.health.business.dto.registries.*;
import com.sunwayhorizo.health.business.patad.empi.query.*;
import com.sunwayhorizo.health.business.patad.encounter.query.*;
import com.sunwayhorizo.health.business.registries.employee.*;
import com.sunwayhorizo.health.business.registries.place.*;
import com.sunwayhorizo.health.business.registries.threelevels.*;
import com.sunwayhorizo.health.common.*;
import com.sunwayhorizo.health.common.validateGroups.*;
import com.sunwayhorizo.health.hl7.common.*;
import com.sunwayhorizo.health.hl7.datatypes.*;
import com.sunwayhorizo.health.hl7.persistent.*;
import com.sunwayhorizo.health.hl7.rim.*;
import com.sunwayhorizo.health.hl7.rim.Role;
import com.sunwayhorizo.health.hl7.vocabulary.*;

@Name("ReceivingManager")
@Stateless
public class ReceivingManager extends BaseManager implements ReceivingManagerLocal
{
    private EmrManagerLocal emrManager = (EmrManagerLocal) Component.getInstance("EmrManager");
    private PatientEncounterQueryLocal patientEncounterQuery = (PatientEncounterQueryLocal) Component.getInstance("PatientEncounterQuery");
    private PatientQueryLocal patientQuery = (PatientQueryLocal) Component.getInstance("PatientQuery");
    private ValidateUtilLocal validateUtil = (ValidateUtilLocal) Component.getInstance("ValidateUtil");
    private EmployeeManagerLocal employeeManager = (EmployeeManagerLocal) Component.getInstance("EmployeeManager");
    private PatientEncounterCommonManagerLocal commonManager = (PatientEncounterCommonManagerLocal) Component
        .getInstance("PatientEncounterCommonManager");
    private ThreeLevelsPhysicianManagerLocal threeManager = (ThreeLevelsPhysicianManagerLocal) Component.getInstance("ThreeLevelsPhysicianManager");
    private AdmitManagerLocal admitManager = (AdmitManagerLocal) Component.getInstance("AdmitManager");
    private BedManagerLocal bedManager = (BedManagerLocal) Component.getInstance("BedManager");


    // 入科
    public ResultsDTO newReceiving(PatientEncounterDTO patientEncounterDTO) throws Hl7Exception
    {

        ResultsDTO resultsDTO = validateReceiving(patientEncounterDTO);
        if (resultsDTO != null)
        {
            return resultsDTO;
        }

        // 就诊号
        String encounterId = patientEncounterDTO.getEncounterID();

        // 判断登记或者转科动作是否为空
        PatientEncounter inhosAct = patientEncounterQuery.findActiveInhosActByII(encounterId);
        PatientEncounter tranferAct = patientEncounterQuery.findLastActiveTransfer(encounterId);

        if (null != inhosAct)
        {
            log.info("找到入院登记动作");
        }
        else if (null != tranferAct)
        {
            log.info("找到转科登记动作");
        }
        else
        {
            log.info("找不到入院登记或者转科信息:" + encounterId);
            return getResultsDTO("入科失败", true, false);
        }

        // 构建入科动作
        PatientEncounter receivingEncounterAct = constructIndepartAct(patientEncounterDTO);

        // 护士参与
        Employee empRole = (Employee) employeeManager.findEmployeeDetail(0l, patientEncounterDTO.getLoginBaseInfo().getOperateId());
        if (empRole == null)
        {
            empRole = employeeManager.findEmployeeDetail(0l, "12345");
            log.info("使用默认操作员");
        }
        else
        {
            log.info("成功得到医生/护士角色");
        }
        ActParticipation empPart = getActFactory().newActParticipation();
        empPart.setTypeCode(ParticipationType.ADM);
        addParticipation(empRole, empPart);

        // 入科患者参与
        Patient patient = (Patient) patientQuery.findRoleById(Long.parseLong(patientEncounterDTO.getPatientBaseInfoDTO().getPersonId()));
        if (patient != null)
        {
            log.info("成功得到患者角色");
        }
        else
        {
            log.info("ReceivingManager-newReceiving-患者为空！！");
            return getResultsDTO("患者为空", true, false);
        }
        ActParticipation patientPart = getActFactory().newActParticipation();
        patientPart.setTypeCode(ParticipationType.SBJ);
        addParticipation(patient, patientPart);

        // 床位参与
        Role bedRole = commonManager.findBedRole(patientEncounterDTO);
        if (bedRole == null)
        {
            log.info("ReceivingManager-newReceiving-床位为空!");
            return getResultsDTO("床位为空,请选择正确的床位", true, false);
        }
        ActParticipation bedPart = getActFactory().newActParticipation();
        bedPart.setTypeCode(ParticipationType.ELOC);
        addParticipation(bedRole, bedPart);

        // 完成一次住院入科
        ControlAct controlAct = newControlAct(receivingEncounterAct);

        log.info(patient.getRoleId() + "患者入科成功,入科就诊号为" + encounterId);

        save(controlAct);
        // 更新床位状态为已占用
        bedManager.modifyBedStatus(bedRole, EntityStatus.UUESBED);
        // 更新入院
        commonManager.updatePateintEncounter(inhosAct, ActStatus.COMPLETED);
        // 更新转科
        commonManager.updatePateintEncounter(tranferAct, ActStatus.COMPLETED);

        return getResultsDTO("入科成功", true, true);
    }


    // 接诊
    public ResultsDTO newReceivingAdmit(PatientEncounterDTO patientEncounterDTO) throws Hl7Exception
    {
        ResultsDTO resultsDTO = validateReceivingAdmit(patientEncounterDTO);
        if (resultsDTO != null)
        {
            return resultsDTO;
        }

        // 接诊动作
        PatientEncounter receivingEncounterAct = constructReceivingAct(patientEncounterDTO);

        // 经治医师
        Employee recevEmp = employeeManager.findEmployeeDetail(0l, patientEncounterDTO.getLoginBaseInfo().getOperateId());
        if (recevEmp == null)
        {
            recevEmp = employeeManager.findEmployeeDetail(0l, "12345");
            log.info("使用默认接诊医生员工号:12345");
        }
        else
        {
            log.info("成功得到医生角色");
        }
        ActParticipation part1 = getActFactory().newActParticipation();
        part1.setTypeCode(ParticipationType.ESC);
        addParticipation(recevEmp, part1);

        // 主治医师
        Employee mainEmp = findMainEmpByRecevEmp(recevEmp);
        if (mainEmp != null)
        {
            ActParticipation part2 = getActFactory().newActParticipation();
            part2.setTypeCode(ParticipationType.DIS);
            addParticipation(mainEmp, part2);
        }

        // 主任医师
        Employee officerEmp = findOfficerEmpByRecevEmp(recevEmp);
        if (officerEmp != null)
        {
            ActParticipation part3 = getActFactory().newActParticipation();
            part3.setTypeCode(ParticipationType.CON);
            addParticipation(officerEmp, part3);
        }

        // 接诊患者
        Patient patient = patientQuery.findPatientByNeturalId(patientEncounterDTO.getPatientBaseInfoDTO().getNatureId());
        if (patient != null)
        {
            log.info("成功得到患者角色");
        }
        else
        {
            log.info("ReceivingManager-newReceiving-患者为空！！");
            return getResultsDTO("患者为空", true, false);
        }
        ActParticipation patientPart = getActFactory().newActParticipation();
        patientPart.setTypeCode(ParticipationType.SBJ);
        addParticipation(patient, patientPart);

        // 接诊Act与入科Act建立关系
        PatientEncounter indepatAct = patientEncounterQuery.findActiveIndepartmentActByII(patientEncounterDTO.getEncounterID());
        if (indepatAct == null)
        {
            log.info("找不到入科动作，接诊失败");
            return getResultsDTO("找不到入科动作，接诊失败", true, false);
        }
        ActRelationship relation = getActFactory().newActRelationship();
        relation.setTypeCode(ActRelationshipType.SBS);
        addRelationship(indepatAct, relation, Direction.TARGET);

        // 病历开启
        Document document = getDocument(patientEncounterDTO, patient, recevEmp);
        if (document != null)
        {
            ActRelationship docRelation = getActFactory().newActRelationship();
            docRelation.setTypeCode(ActRelationshipType.COMP);
            addRelationship(document, docRelation, Direction.SOURCE);
        }

        ControlAct controlAct = newControlAct(receivingEncounterAct);
        save(controlAct);

        log.info(patient.getRoleId() + "患者接诊成功");
        log.info("接诊Act与电子病历管理Act关联成功");

        return getResultsDTO("接诊成功", true, null);
    }


    // 根据经治医师找到主治医师
    private Employee findMainEmpByRecevEmp(Employee recevEmp) throws Hl7Exception
    {
        ThreeLevelsPhysicianDTO threeDTO = threeManager.findThreeLevelsDTOByDoctId(recevEmp.getRoleId() + "");
        if (threeDTO != null && threeDTO.getAttendingPhysicianId() != null)
        {
            return employeeManager.findEmployeeDetail(Long.parseLong(threeDTO.getAttendingPhysicianId()), null);
        }
        return null;
    }


    // 根据经治医师找到主任医师
    private Employee findOfficerEmpByRecevEmp(Employee recevEmp) throws Hl7Exception
    {
        ThreeLevelsPhysicianDTO threeDTO = threeManager.findThreeLevelsDTOByDoctId(recevEmp.getRoleId() + "");
        if (threeDTO != null && threeDTO.getChiefDoctorId() != null)
        {
            return employeeManager.findEmployeeDetail(Long.parseLong(threeDTO.getChiefDoctorId()), null);
        }
        return null;
    }


    // 查询待接诊列表
    @Override
    public ResultsDTO findAdmitReceivingList(String workgroupId, PageDTO pageDTO) throws Hl7Exception
    {

        if (StrUtil.isEmpty(workgroupId))
        {
            log.info("ReceivingManager-findAdmitReceivingList-workgroupId为空！");
            return getResultsDTO("", true, false);
        }

        List<PatientEncounter> list = patientEncounterQuery.findAllActiveIndepartments(workgroupId, pageDTO.getPageNo(), pageDTO.getPageSize());

        List<PatientEncounterDTO> patEncList = new ArrayList<PatientEncounterDTO>();

        for (PatientEncounter encounter : list)
        {

            PatientEncounterDTO dto = new PatientEncounterDTO();

            admitManager.convertPatientEncounterDTO(dto, findInHospitableEncounterByInDepartmentEncounter(encounter));

            convertIndepartement(dto, encounter);

            patEncList.add(dto);

            Hl7NullRemover.removeHl7Null(dto);

        }

        pageDTO.setTotalRecord((int) patientEncounterQuery.findAllActiveIndepartmentsCount(workgroupId));

        log.info("该工作组下有" + pageDTO.getTotalRecord() + "个患者需要接诊");
        return getResultsDTO("该工作组下有" + pageDTO.getTotalRecord() + "个患者需要接诊", true, patEncList, pageDTO);

    }


    // 组装入科动作
    @Override
    public PatientEncounterDTO converByIndepartment(PatientEncounter p) throws Hl7Exception
    {
        PatientEncounterDTO dto = new PatientEncounterDTO();
        admitManager.convertPatientEncounterDTO(dto, findInHospitableEncounterByInDepartmentEncounter(p));
        convertIndepartement(dto, p);
        Hl7NullRemover.removeHl7Null(dto);
        return dto;
    }


    // 根据接诊动作组装病例信息
    @Override
    public PatientEncounterDTO findByRecieveEncounter(PatientEncounter recieveEncounter) throws Hl7Exception
    {
        PatientEncounterDTO dto = new PatientEncounterDTO();
        Map<CS, PatientEncounter> encounters = findEncountersByRecieveEncounter(recieveEncounter);

        admitManager.convertPatientEncounterDTO(dto, encounters.get(ActCode.HOSPITALIZED));
        convertIndepartement(dto, encounters.get(ActCode.INDEPARTMENT));
        convertRecieveEncounter(recieveEncounter, dto);
        return dto;
    }


    // 组装接诊三级医生
    @Override
    public PatientEncounterDTO convertRecieveEncounter(PatientEncounter recieveEncounter, PatientEncounterDTO dto) throws Hl7Exception
    {

        if (recieveEncounter != null)
        {
            for (ActParticipation part : recieveEncounter.getParticipations())
            {

                if (part.getTypecode().equals(ParticipationType.ESC))
                {
                    Employee esc = (Employee) part.getRoleparticipation();
                    dto.getInDepartment().getThreeLevelsPhysicianDTO()
                        .setDoctorName(esc.getPlayerEntity().getNameByUse(EntityNameUse.L).formatted().stringValue());
                    dto.getInDepartment().getThreeLevelsPhysicianDTO().setDoctorId(esc.getRoleId().toString());
                    continue;
                }
                else if (part.getTypecode().equals(ParticipationType.DIS))
                {

                    Employee dis = (Employee) part.getRoleparticipation();
                    dto.getInDepartment().getThreeLevelsPhysicianDTO()
                        .setAttendingPhysicianName(dis.getPlayerEntity().getNameByUse(EntityNameUse.L).formatted().stringValue());
                    dto.getInDepartment().getThreeLevelsPhysicianDTO().setAttendingPhysicianId(dis.getRoleId().toString());
                    continue;

                }
                else if (part.getTypecode().equals(ParticipationType.CON))
                {
                    Employee con = (Employee) part.getRoleparticipation();
                    dto.getInDepartment().getThreeLevelsPhysicianDTO()
                        .setChiefDoctorName(con.getPlayerEntity().getNameByUse(EntityNameUse.L).formatted().stringValue());
                    dto.getInDepartment().getThreeLevelsPhysicianDTO().setChiefDoctorId(con.getRoleId().toString());
                    continue;
                }

            }
        }
        return dto;
    }


    @Override
    // 根据接诊动作查询入科、入院动作
    public Map<CS, PatientEncounter> findEncountersByRecieveEncounter(PatientEncounter recieveEncounter) throws Hl7Exception
    {
        Map<CS, PatientEncounter> map = new java.util.HashMap<CS, PatientEncounter>();
        PatientEncounter inHospitalEncounter = null;
        PatientEncounter inDepartmentEncounter = null;

        String encounterId = recieveEncounter.getId(ActIICode.RECEIVING).clinicNo().stringValue();

        inDepartmentEncounter = patientEncounterQuery.findLastIndepartment(encounterId);

        inHospitalEncounter = findInHospitableEncounterByInDepartmentEncounter(inDepartmentEncounter);
        map.put(ActCode.HOSPITALIZED, inHospitalEncounter);
        map.put(ActCode.INDEPARTMENT, inDepartmentEncounter);
        return map;
    }


    // 根据入科动作查询入院动作
    public PatientEncounter findInHospitableEncounterByInDepartmentEncounter(PatientEncounter inDepartmentEncounter) throws Hl7Exception
    {
        PatientEncounter inHospitalEncounter = null;
        long start = System.currentTimeMillis();

        String encounterId = inDepartmentEncounter.getId(ActIICode.INDEPARTMENT) != null ? inDepartmentEncounter.getId(ActIICode.INDEPARTMENT)
            .clinicNo().stringValue() : null;
        // 获取入院动作
        if (encounterId != null)
        {
            inHospitalEncounter = patientEncounterQuery.findLastInhosActByEncounterId(encounterId);
        }

        log.info("查找关联入院动作消耗" + (System.currentTimeMillis() - start) / 1000.0 + "秒");
        return inHospitalEncounter;
    }


    // 根据入科动作组装dto
    @Override
    public PatientEncounterDTO convertIndepartement(PatientEncounterDTO dto, PatientEncounter encounter) throws Hl7Exception
    {

        // 入科时间
        if (encounter.getActivityTime() != null)
        {
            dto.getInDepartment().setAdmissionTime(DateUtil.formatDate(encounter.getActivityTime().hull().low().toDate(), "yyyy-MM-dd HH:mm:ss"));
            // 住院天数
            dto.getInDepartment().setInHosTime(DateUtil.fromNow(encounter.getActivityTime().hull().low().toDate()));
        }
        // 设置入科动作ID
        if (encounter.getActId() != null && encounter.getActId() != 0l)
        {
            dto.setActIdInDepartment(encounter.getActId() + "");
        }
        // 设置跟踪状态
        if (encounter.getNegationInd().isTrue())
        {
            dto.setTrackFlag("1");
        }
        else
        {
            dto.setTrackFlag("0");
        }
        for (ActParticipation prt : encounter.getParticipations())
        {
            if (prt.getTypecode().equals(ParticipationType.ELOC))
            {
                Hl7Entity bed = prt.getRole().getPlayerEntity();
                Organization workgroup = (Organization) prt.getRole().getScoperEntity();

                if (!ListUtil.isEmpty(bed.getEntyNamesList()))
                {
                    // 床位号
                    dto.getInDepartment().setBedNO(bed.getNameByUse(EntityNameUse.L).formatted().stringValue());
                }
                if (!ListUtil.isEmpty(workgroup.getEntyNamesList()))
                {
                    // 工作组
                    for (RimCoreRoles r : workgroup.getPlayerRimCoreRolesList())
                    {
                        if (r.getCode().code().equals(RoleCode.WORKGROUP.code()))
                        {
                            dto.getInDepartment().setWorkGroupId(r.getRoleId().toString());
                            break;
                        }
                    }
                    dto.getInDepartment().setWorkgroupName(workgroup.getNameByUse(EntityNameUse.L).formatted().stringValue());
                    // dto.getTransferDTO().setFromWorkgroupCode(workgroupRole.getId(RoleIICode.DEPTCODE).extension().stringValue());
                }
                break;
            }
            // else if (prt.getTypecode().equals(ParticipationType.SBJ))
            // {
            // Patient patient = (Patient) prt.getRole();
            // commonManager.convertByPatient(dto, patient);
            // continue;
            // }
        }
        return dto;
    }


    // 根据医生查询她的患者
    @Override
    public ResultsDTO findPatientsByDoctor(String roleId, PageDTO pageDTO) throws Hl7Exception
    {
        List<String> statusCode = new ArrayList<String>();
        statusCode.add("0");
        statusCode.add("4");
        return findPatientsByDoctor(roleId, statusCode, pageDTO);
    }


    // 根据医生查询她的患者
    @Override
    public ResultsDTO findPatientsByDoctor(String roleId, List<String> statusCode, PageDTO pageDTO) throws Hl7Exception
    {
        if (pageDTO == null)
        {
            pageDTO = new PageDTO();
        }
        em.clear();
        List<PatientEncounter> list = null;

        list = patientEncounterQuery.findPatientEncountersByDoctorRoleIdAndStatusCode(roleId, statusCode, pageDTO.getPageNo(), pageDTO.getPageSize());

        List<PatientEncounterDTO> patEncList = new ArrayList<PatientEncounterDTO>();
        for (PatientEncounter encounter : list)
        {
            PatientEncounterDTO dto = findByRecieveEncounter(encounter);
            dto.getEmrControllerDTO().setCompletionCode(getEmrCodeByRecievingEncounter(encounter));

            patEncList.add(dto);

            Hl7NullRemover.removeHl7Null(dto);

        }
        if (ListUtil.isEmpty(patEncList))
        {
            log.info("该医生已接诊的患者");
            return this.getResultsDTO("该医生没有已接诊的患者", true, null);

        }
        int total = (int) patientEncounterQuery.findMyPatientsByDoctorCount(roleId, statusCode);
        log.info("该医生有" + total + "个患者已接诊");

        pageDTO.setTotalRecord(total);

        log.info("该医生有" + pageDTO.getTotalRecord() + "个患者已接诊");
        return this.getResultsDTO("该医生有" + pageDTO.getTotalRecord() + "个患者已接诊", true, patEncList, pageDTO);
    }


    // 根据住院号(病案号)查询所有已接诊患者
    @Override
    public ResultsDTO findPatientsByPatientId(String hospitalNo) throws Hl7Exception
    {

        em.clear();
        List<PatientEncounter> list = patientEncounterQuery.findAllReceivingByPatientId(hospitalNo);
        List<PatientEncounterDTO> patEncList = new ArrayList<PatientEncounterDTO>();
        for (PatientEncounter encounter : list)
        {
            PatientEncounterDTO dto = findByRecieveEncounter(encounter);
            dto.getEmrControllerDTO().setCompletionCode(getEmrCodeByRecievingEncounter(encounter));

            Hl7NullRemover.removeHl7Null(dto);
            patEncList.add(dto);
        }

        if (ListUtil.isEmpty(patEncList))
        {
            log.info("该医生已接诊的患者");
            return this.getResultsDTO("该医生没有已接诊的患者", true, null);

        }

        return this.getResultsDTO("查询到已接诊患者", true, patEncList);
    }


    // 获得病理状态信息根据接诊动作
    @Override
    public String getEmrCodeByRecievingEncounter(PatientEncounter encounter) throws Hl7Exception
    {
        for (RimCoreActRelations relations : encounter.getSourceActRelationsList())
        {
            ActRelationship re = (ActRelationship) relations;
            if (re.getTypeCode().equals(ActRelationshipType.COMP) && re.getTargetAct().getClassCode().equals(ActClass.DOC))
            {
                {
                    return re.getTargetAct().getStatusCode().code().stringValue();
                }
            }
        }
        return "";
    }


    @Override
    public ResultsDTO findAdmitReceivingListByWorkgroupIds(String workgroupRoleId, PageDTO pageDTO) throws Hl7Exception
    {
        List<String> statusCode = new ArrayList<String>();
        statusCode.add("0");
        statusCode.add("4");
        return findAdmitReceivingListByWorkgroupIds(workgroupRoleId, statusCode, pageDTO);
    }


    @Override
    // 根据就诊号修改接诊医生
    public ResultsDTO updateDoctorByPatientId(String id, Employee emp) throws Hl7Exception
    {
        String badinfo = "";
        if (id == null || id.equals("") || emp == null)
        {
            badinfo = "就诊号和接诊医生不能为空！";
            log.info("ReceivingManager-updateDoctorByPatientId-" + badinfo);
            return getResultsDTO(badinfo, true, false);
        }

        RimCoreActPrtcptns prt = patientEncounterQuery.findRecieveingEncounterById(id);
        if (prt == null)
        {
            badinfo = "未找到相关接诊动作";
            log.info("ReceivingManager-updateDoctorByPatientId-" + badinfo);
            return getResultsDTO(badinfo, true, false);
        }
        prt.setRoleparticipation(emp);
        update(prt);
        String goodInfo = "修改接诊医生成功！";
        log.info("ReceivingManager-updateDoctorByPatientId-" + goodInfo);
        return getResultsDTO(goodInfo, true, true);
    }


    // 根据病区查询已接诊患者信息
    @Override
    public ResultsDTO findAdmitReceivingListByWorkgroupIds(String workgroupRoleId, List<String> statusCode, PageDTO pageDTO) throws Hl7Exception
    {
        em.clear();
        List<PatientEncounter> list = patientEncounterQuery.findPatientEncountersByWorkgroupIdsAndStatusCode(workgroupRoleId, statusCode,
            pageDTO.getPageNo(), pageDTO.getPageSize());
        List<PatientEncounterDTO> patEncList = new ArrayList<PatientEncounterDTO>();
        for (PatientEncounter encounter : list)
        {
            PatientEncounterDTO dto = findByRecieveEncounter(encounter);
            dto.getEmrControllerDTO().setCompletionCode(getEmrCodeByRecievingEncounter(encounter));
            patEncList.add(dto);
            Hl7NullRemover.removeHl7Null(dto);

        }
        for (PatientEncounterDTO dto : patEncList)
        {
            log.info(dto);
        }
        if (ListUtil.isEmpty(patEncList))
        {
            log.info("该工作组下没有已接诊的患者");
            return this.getResultsDTO("该工作组下没有已接诊的患者", true, null);
        }
        int total = (int) patientEncounterQuery.findMyPatientInGroup(workgroupRoleId, statusCode);
        pageDTO.setTotalRecord(total);

        log.info("该工作组下有" + pageDTO.getTotalRecord() + "个患者已接诊");
        return this.getResultsDTO("该工作组下有" + pageDTO.getTotalRecord() + "个患者已接诊", true, patEncList, pageDTO);
    }


    // 查询转科列表
    @Override
    public ResultsDTO findPatientsByWorkgroupId(String workgroupId, PageDTO dto) throws Hl7Exception
    {
        dto.setTotalRecord((int) patientEncounterQuery.findCountIndepartment(workgroupId));
        return getResultsDTO("成功返回", true, findPatientsByWorkGroupId(workgroupId, dto), dto);
    }


    // 查询转科列表
    @Override
    public List<PatientEncounterDTO> findPatientsByWorkGroupId(String workgroupId, PageDTO dto) throws Hl7Exception
    {

        List<PatientEncounterDTO> pdtos = new ArrayList<PatientEncounterDTO>();
        for (PatientEncounter p : patientEncounterQuery.findIndepartment(workgroupId, dto.getPageNo(), dto.getPageSize()))
        {
            pdtos.add(converByIndepartment(p));
        }
        return pdtos;
    }


    // 验证转科
    private ResultsDTO validateReceiving(PatientEncounterDTO patientEncounterDTO) throws Hl7Exception
    {

        ResultsDTO resultDTO = validateUtil.verifiedReturnResultsDTO(patientEncounterDTO, NewReceiving.class);
        if (resultDTO != null)
        {
            log.info(resultDTO.getResultDesc());
            return resultDTO;
        }

        String encounterId = patientEncounterDTO.getEncounterID();

        // 获取上次入科信息
        PatientEncounter lastActiveIndepartment = patientEncounterQuery.findActiveIndepartmentActByII(encounterId);
        if (lastActiveIndepartment != null)
        {
            log.info("患者已在科，不能重复入科");
            return getResultsDTO("患者已在科，不能重复入科", true, false);
        }

        return null;
    }


    private ResultsDTO validateReceivingAdmit(PatientEncounterDTO patientEncounterDTO) throws Hl7Exception
    {
        ResultsDTO resultDTO = validateUtil.verifiedReturnResultsDTO(patientEncounterDTO, NewReceivingAdmit.class);
        if (resultDTO != null)
        {
            log.info(resultDTO.getResultDesc());
            return resultDTO;
        }

        String encounterId = patientEncounterDTO.getEncounterID();

        // 获取上次接诊信息
        PatientEncounter lastActiveIndepartment = patientEncounterQuery.findActiveRecieveingEncounterById(encounterId);
        if (lastActiveIndepartment != null)
        {
            log.info("患者已接诊，不能重复接诊");
            return getResultsDTO("患者已接诊，不能重复接诊", true, false);
        }
        return null;
    }


    // 构建入科
    private PatientEncounter constructIndepartAct(PatientEncounterDTO patientEncounterDTO) throws Hl7Exception
    {

        CE ce = this.getDataTypeFactory().newCE(ActCode.INDEPARTMENT.code().toString());
        PatientEncounter receivingAct = this.getActFactory().newPatientEncounter(ActMood.EVN, ce, null);
        log.info("构建入科");

        // 患者已被入科状态
        receivingAct.setStatusCode(ActStatus.ACTIVE);

        // 就诊号
        receivingAct.setId(commonManager.getEcounterIdForOther(patientEncounterDTO, ActCode.INDEPARTMENT));
        // 入科时间
        if (StrUtil.isNotEmpty(patientEncounterDTO.getInDepartment().getAdmissionTime()))
        {
            Date date = DateUtil.getDateBy3String(patientEncounterDTO.getInDepartment().getAdmissionTime());
            receivingAct.setActivityTime(DataTypeUtil.getGTS(DataTypeUtil.getIVL_TS(date, date)));
        }
        else
        {
            Date date = new Date();
            receivingAct.setActivityTime(DataTypeUtil.getGTS(DataTypeUtil.getIVL_TS(date, date)));
        }
        return receivingAct;
    }


    // 获取新的接诊动作
    @Override
    public PatientEncounter getNewReceiving(String patientId, Document doc) throws Hl7Exception
    {

        PatientEncounter pe = null;
        for (ActRelationship rel : doc.getTargetActRelationship())
        {
            if (rel.getTypeCode().equals(ActRelationshipType.COMP) && rel.getSourceAct().getCode().code().equals(ActCode.RECEIVING.code()))
            {
                if (!ActRelationshipSplit.E1.equals(rel.getSplitCode()))
                {
                    pe = (PatientEncounter) rel.getSourceAct();
                }
                rel.setSplitCode(ActRelationshipSplit.E1);
                update(rel);
                break;
            }
        }
        PatientEncounter newReceving = patientEncounterQuery.findLastReceving(patientId);

        if (pe != null && pe.getActId() != newReceving.getActId())
        {
            return newReceving;
        }

        return null;
    }


    // 打回上次病历还原
    @Override
    public void returnLastRemove(String patientId, Document doc) throws Hl7Exception
    {

        PatientEncounter lastRemoved = patientEncounterQuery.findLastRemoved(patientId);

        for (ActRelationship rel : lastRemoved.getSourceActRelationship())
        {
            if (rel.getTypeCode().equals(ActRelationshipType.COMP))
            {
                rel.setSplitCode(null);
                update(rel);
            }
        }
    }


    // 构建接诊
    private PatientEncounter constructReceivingAct(PatientEncounterDTO patientEncounterDTO) throws Hl7Exception
    {
        // 住院接诊

        CE ce = this.getDataTypeFactory().newCE(ActCode.RECEIVING.code().toString());
        PatientEncounter receivingEncounterAct = this.getActFactory().newPatientEncounter(ActMood.EVN, ce, null);

        // 保存住院接诊就诊号
        receivingEncounterAct.setId(commonManager.getEcounterIdForOther(patientEncounterDTO, ActCode.RECEIVING));

        // 接诊时间
        Date date = new Date();
        receivingEncounterAct.setActivityTime(DataTypeUtil.getGTS(DataTypeUtil.getIVL_TS(date, date)));

        // 患者已被接诊状态
        receivingEncounterAct.setStatusCode(ActStatus.ACTIVE);

        log.info("构建住院接诊");
        return receivingEncounterAct;
    }


    // 构建病历
    private Document constructDocment(PatientEncounterDTO dto, Patient p, Employee ee) throws Hl7Exception
    {
        EmrManagerDTO emrControllerDTO = new EmrManagerDTO();
        emrControllerDTO.setPatientId(String.valueOf(p.getRoleId()));
        emrControllerDTO.setRimRoleId(String.valueOf(ee.getRoleId()));
        emrControllerDTO.setCompletionCode("0");
        emrControllerDTO.setPatientNum(dto.getInHospitalDTO().getEncounterNum()); // 需要设置患者的住院次数
        emrControllerDTO.getLoginBaseInfoDTO().setOperateId(String.valueOf(ee.getRoleId()));
        Document document = emrManager.newEmrManager(emrControllerDTO);
        return document;
    }


    // 判断病历状态
    private Document getDocument(PatientEncounterDTO dto, Patient p, Employee ee) throws Hl7Exception
    {

        Document document = emrManager.findEmrManagerByPatientId(p.getRoleId().toString(), dto.getInHospitalDTO().getEncounterNum());
        if (document == null)
        {
            document = constructDocment(dto, p, ee);
            return document;
        }
        else if (document.getStatusCode().equals(DataTypeUtil.getCS("0")) || document.getStatusCode().equals(DataTypeUtil.getCS("3")))
        {
            document.setStatusCode(DataTypeUtil.getCS("0"));
            update(document);
            return document;
        }
        else
        {
            return null;
        }
    }


    // 修改三级医师
    @Override
    public ResultsDTO update3Levels(ThreeLevelsPhysicianDTO dto) throws Hl7Exception
    {

        em.clear();
        PatientEncounter pe = patientEncounterQuery.findActiveRecieveingEncounterById(dto.getEncounteId());
        Role esc = patientQuery.findRoleById(Long.parseLong(dto.getDoctorId()));
        Role dis = patientQuery.findRoleById(Long.parseLong(dto.getAttendingPhysicianId()));
        Role con = patientQuery.findRoleById(Long.parseLong(dto.getChiefDoctorId()));

        boolean disIsNull = true;
        boolean conIsNull = true;
        for (ActParticipation part : pe.getParticipations())
        {

            if (part.getTypecode().equals(ParticipationType.ESC))
            {

                if (esc != null && !esc.getRoleId().equals(part.getRoleparticipation().getRoleId()))
                {
                    part.setRoleparticipation(esc);
                    em.merge(part);
                    log.info("ReceivingManager-update3Levels- 更新经治医师!");
                }
                else
                {
                    log.info("ReceivingManager-update3Levels-查询不到经治医师或者经治医师不变!");
                }
                continue;
            }
            else if (part.getTypecode().equals(ParticipationType.DIS))
            {
                conIsNull = false;
                if (StrUtil.isEmpty(dto.getAttendingPhysicianId()))
                {
                    log.info("ReceivingManager-update3Levels- 主治医师id为空!");
                    continue;
                }

                if (dis != null && !dis.getRoleId().equals(part.getRoleparticipation().getRoleId()))
                {
                    part.setRoleparticipation(dis);
                    em.merge(part);
                    log.info("ReceivingManager-update3Levels- 更新主治医师!");
                }
                else
                {
                    log.info("ReceivingManager-update3Levels-查询不到主治医师或者主治医师不变!");
                }
                continue;

            }
            else if (part.getTypecode().equals(ParticipationType.CON))
            {
                disIsNull = false;
                if (StrUtil.isEmpty(dto.getChiefDoctorId()))
                {
                    log.info("ReceivingManager-update3Levels- 主任医师id为空!");
                    continue;
                }

                if (con != null && !con.getRoleId().equals(part.getRoleparticipation().getRoleId()))
                {
                    part.setRoleparticipation(con);
                    em.merge(part);
                    log.info("ReceivingManager-update3Levels- 更新主任医师!");
                }
                else
                {
                    log.info("ReceivingManager-update3Levels- 查询不到主任医师或者主任医师不变!");
                }
                continue;
            }
        }
        if (disIsNull && dis != null)
        {
            ActParticipation disPart = getActFactory().newActParticipation();
            disPart.setTypeCode(ParticipationType.DIS);
            disPart.setRoleparticipation(dis);
            disPart.setParticipationAct(pe);
            pe.getParticipations().add(disPart);
            em.persist(disPart);

            log.info("ReceivingManager-update3Levels- 新增主治医师！");
        }
        if (conIsNull && con != null)
        {
            ActParticipation conPart = getActFactory().newActParticipation();
            conPart.setTypeCode(ParticipationType.CON);
            conPart.setRoleparticipation(con);
            conPart.setParticipationAct(pe);
            pe.getParticipations().add(conPart);
            em.persist(conPart);
            log.info("ReceivingManager-update3Levels- 新增主任医师！");
        }
        em.flush();
        em.clear();
        log.info("ReceivingManager-update3Levels- 更新三级医师成功!");
        return getResultsDTO("更新三级医师成功!", true, true);
    }

}
